package com.subfg.common.util.common;


import com.subfg.common.constant.TimeEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.util.Calendar;
import java.util.Date;

/**
 * 时间工具类
 */
@Component
public class TimeUtil {
    private Logger log = LoggerFactory.getLogger(TimeUtil.class);
    // 年-月-日 小时:分钟:秒   获取日期格式精确到秒
    private static SimpleDateFormat currentData = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    // 年-月-日
    private static SimpleDateFormat formatData = new SimpleDateFormat("yyyy-MM-dd");
    // 年 月 日
    private static SimpleDateFormat dataFormatter = new SimpleDateFormat("yyMMdd");
    // 年 月
    private static SimpleDateFormat monthFormatter = new SimpleDateFormat("yyMM");
    // 年
    private static SimpleDateFormat yearFormatter = new SimpleDateFormat("yyyy");

    /** 根据不同格式返回不同日期格式 (不带-的) **/
    public static String getCurrentData(TimeEnum timeEnum) {
        String currentStr = new String();
        Date date = new Date();
        switch (timeEnum) {
            case DAY:
                // yyMMdd
                currentStr = dataFormatter.format(date);
                break;
            case MONTH:
                // yyMM
                currentStr = monthFormatter.format(date);
                break;
            case YEAR:
                // yyyy
                currentStr = yearFormatter.format(date);
                break;
            default:
                currentStr = dataFormatter.format(date);
                break;
        }
        return currentStr;
    }

    /** 获取现在时间 yyyy-MM-dd HH:mm:ss **/
    public static String getCurrentData() {
        Date date = new Date();
        return currentData.format(date);
    }
    /** 获取当前时间戳 **/
    public static long getCurrentTime() {
        return System.currentTimeMillis() / 1000;
    }


    /** 这个时间段的 月份有多少天 **/
    public static Integer currenTimeDay(Long timestamp) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(timestamp);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }
    /** 获取本月有多少天 **/
    public static Integer currenTimeDay() {
        return currenTimeDay(System.currentTimeMillis());
    }

    /** 两个时间戳 相差多少天 [不满一天 按 一天算] **/
    public static Integer timeDiscrepancy(Long startTimeStamp, Long endTimeStamp, Integer sumDay) {
        if (startTimeStamp.longValue() >= endTimeStamp.longValue()) {
            return sumDay;
        }
        Instant instant1 = Instant.ofEpochMilli(startTimeStamp);
        Instant instant2 = Instant.ofEpochMilli(endTimeStamp);
        Duration duration = Duration.between(instant1, instant2);
        long day = duration.toDays();
        return (int) day + 1;
    }


    /** 根据TimeEnum 计算返回多少秒的 **/
    public static long getTimeEnumSecode(Integer num, TimeEnum timeEnum) {
        long compute = 0;
        switch (timeEnum) {
            case WEEK:
                // 计算出(num) 周 以后的时间搓
                compute = 60 * 60 * 24 * 7 * num;
                break;
            case DAY:
                // 计算出(num) 天 以后的时间搓
                compute = 60 * 60 * 24 * num;
                break;
            case HOUR:
                // 计算出(num) 小时 以后的时间搓
                compute = 60 * 60 * num;
                break;
            case MINUTE:
                // 计算出(num) 分钟 以后的时间搓
                compute = 60 * num;
                break;
            case SECOND:
                // 计算出(num) 秒 以后的 时间搓
                compute = num;
                break;
        }
        return compute;
    }

    /** 根据选择的日期类型, 返回现在计算号的时间戳 **/
    private static long getChooseTimeStamp(Integer num, Long timestamp, TimeEnum timeEnum) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(timestamp);
        switch (timeEnum) {
            case YEAR:
                // 计算出(num) 年 以后的时间搓
                calendar.add(Calendar.YEAR, num);
                break;
            case QUARTER:
                // 计算出(num) 年季度 以后的时间搓
                calendar.add(Calendar.MONTH, 3 * num);
                break;
            case MONTH:
                // 计算出(num) 月 以后的时间搓
                calendar.add(Calendar.MONTH, num);
                break;
            case WEEK:
                // 计算出(num) 周 以后的时间搓
                calendar.add(Calendar.WEDNESDAY, num);
                break;
            case DAY:
                // 计算出(num) 天 以后的时间搓
                calendar.add(Calendar.DATE, num);
                break;
            case HOUR:
                // 计算出(num) 小时 以后的时间搓
                calendar.add(Calendar.HOUR, num);
                break;
            case MINUTE:
                // 计算出(num) 分钟 以后的时间搓
                calendar.add(Calendar.MINUTE, num);
                break;
            case SECOND:
                // 计算出(num) 秒 以后的 时间搓
                calendar.add(Calendar.SECOND, num);
                break;
        }
        return calendar.getTimeInMillis();
    }
    /** 根据现在时间毫秒 进行增加 **/
    public static long getCurrentTimeStamp(Integer num, TimeEnum timeEnum) {
        return getChooseTimeStamp(num, System.currentTimeMillis(), timeEnum);
    }
    /** 根据现在时间获取秒 **/
    public static long getCurrentSecode(Integer num, TimeEnum timeEnum) {
        return getCurrentTimeStamp(num, timeEnum) / 1000;
    }
    /** 传入的date, 进行时间加减 **/
    public static long getCurrentTimeStamp(Integer num, Date date, TimeEnum timeEnum) {
        return getChooseTimeStamp(num, date.getTime(), timeEnum);
    }


    /** 根据具体时间 毫秒性 **/
    public static long getCurrentTimeStamp(Integer num, Long timstamp, TimeEnum timeEnum) {
        return getChooseTimeStamp(num, timstamp * 1000, timeEnum);
    }
    /** 根据现在时间获取秒 **/
    public static long getCurrentSecode(Integer num, Long timstamp, TimeEnum timeEnum) {
        return getCurrentTimeStamp(num, timstamp, timeEnum) / 1000;
    }
    /** 获取时间戳 **/
    public static long getTimeEnumTimeStamp(Integer num, TimeEnum timeEnum) {
        return getTimeEnumSecode(num, timeEnum) * 1000;
    }

}
